# coding=utf-8
"""
E浙理打卡
2021-9-2
"""
import json
import re
import schedule
import requests
import time
import E_log
from flask import Flask, request, make_response
from wsgiref.simple_server import make_server
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)


class reportE:
    def __init__(self):
        # 登录请求url
        self.login_url = "http://stu.zstu.edu.cn/webroot/decision/login"
        self.username = "unknown"
        self.password = "unknown"
        # 填报请求url
        self.re_url = "http://stu.zstu.edu.cn/webroot/decision/view/report"

        self.accessToken = ""  # 用户登录密钥
        self.sessionID = ""  # 健康申报表单id

        # 登录headers只需要Host即可
        self.login_headers = {
            "Host": "stu.zstu.edu.cn",
            "User-Agent": "Mozilla/5.0 (Linux; Android 11; Redmi K20 Pro Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045709 Mobile Safari/537.36 MMWEBID/8396 MicroMessenger/8.0.7.1920(0x28000737) Process/tools WeChat/arm64 Weixin NetType/4G Language/zh_CN ABI/arm64",
            "clientType": "mobile/h5_5.0",
            "deviceType": "android",
            "__device__": "android"
        }

    def login(self, username, password):  # 登录函数，传入学号和密码
        """模拟登录客户端获取fine_auth_token登录密钥"""
        # 登录尝试次数过多会限制登录或者需要拖动拼图，还没尝试是限制ip还是账号，有待尝试
        # 登录请求信息
        user_data = {
            "username": username,
            "password": password,
            "validity": "-2",
            "macAddress": "495D3B65C43D86D8UNKNOWN",  # 设备MAC地址，实际测试中不需要授权设备就可以登录
            "deviceName": "Xiaomi Redmi K20 Pro"  # 设备名称
        }

        # 发送登录请求
        html = requests.post(url=self.login_url, json=user_data, headers=self.login_headers).text
        try:
            html = json.loads(html)
            # 获取token
            self.accessToken = html['data']['accessToken']
            self.username = username
            self.password = password
            logger.info("登陆成功！学号：")
            logger.info(html['data']['username'])
            # 用登录信息获取sessionid（表单id）
            self.get_sessionID()
            return 1
        except:
            logger.info(self.username + "," + password + ":登陆失败！返回信息：")
            # 打印返回的登录信息
            reg = re.compile("detail-message\">(.*?)<", re.S)
            temp = reg.findall(html)[0]
            logger.info(temp)
            print("登录失败！" + temp + "\n请重新输入学号和密码！")
            self.login()

    def get_sessionID(self):
        """请求带有表单id的信息,获取SessionID"""

        id_data = requests.get(
            url="http://stu.zstu.edu.cn/webroot/decision/view/report?__pi__=true&op=write&_replaceview_=true&fine_hyperlink=48a400c6-1aec-4a6c-94cb-66581ce24eac&__parameters__=%257B%257D&viewlet=%252Fyewubanli%252F%25E5%2581%25A5%25E5%25BA%25B7%25E7%2594%25B3%25E6%258A%25A5.cpt",
            headers={
                "Host": "stu.zstu.edu.cn",
                "Cookie": "captchaToken=; UM_distinctid=;fine_auth_token=" + self.accessToken
            }
        ).text

        # 获取填报表单id
        try:
            id_data = json.loads(id_data)
            self.sessionID = id_data['sessionid']

        except:
            # 已经打卡会转换出错，但从返回的数据中也可以找到表单的sessionID，可以重复打卡，很神奇
            logger.info(time.strftime("%Y年%m月%d日:", time.localtime()) + "今天已经打过卡了~开始等待打卡~")
            reg = re.compile("SessionID = '(.*?)'", re.S)
            temp = reg.findall(id_data)[0]
            self.sessionID = temp
            # print(temp)
            # print(self.sessionID)
        else:
            # print(id_data)
            # 打印表单id
            logger.info("今天第一次打卡~开始等待打卡~")
            # print(self.sessionID)
            # self.read_by_json()

        # finally:
        #     # 进行填报
        #     self.report()

    def report(self):
        # 请求体data，还得这样写，字典形式不太清楚编码格式
        data = "op=fr_write&cmd=submit_w_report&reportXML=%253C%253Fxml%2520version%253D%25221.0%2522%2520encoding%253D%2522UTF-8%2522%2520%253F%253E%253CWorkBook%253E%253CVersion%253E6.5%253C%252FVersion%253E%253CReport%2520class%253D%2522com.fr.report.WorkSheet%2522%2520name%253D%25220%2522%253E%253CCellElementList%253E%253CC%2520c%253D%25224%2522%2520r%253D%252210%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25223%2522%2520r%253D%252217%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E6%25AD%25A3%25E5%25B8%25B8%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25223%2522%2520r%253D%252219%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B37%25E5%25BA%25A6%25E4%25BB%25A5%25E4%25B8%258B%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25223%2522%2520r%253D%252220%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B37%25E5%25BA%25A6%25E4%25BB%25A5%25E4%25B8%258B%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252229%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252225%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E7%25BB%25BF%25E8%2589%25B2%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252226%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E7%25BB%25BF%25E8%2589%25B2%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252227%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252228%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25223%2522%2520r%253D%25229%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E6%25B5%2599%25E6%25B1%259F%25E7%2590%2586%25E5%25B7%25A5%25E5%25A4%25A7%25E5%25AD%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252238%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252235%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252233%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253CC%2520c%253D%25225%2522%2520r%253D%252231%2522%253E%253CO%2520t%253D%2522S%2522%253E%253C!%255BCDATA%255B%25E5%2590%25A6%255D%255D%253E%253C%252FO%253E%253C%252FC%253E%253C%252FCellElementList%253E%253C%252FReport%253E%253C%252FWorkBook%253E&cutPage="
        # print(time.strftime("%Y年%m月%d日 %H:%M:%S：打卡成功", time.localtime()))
        logger.info("开始打卡。。。。")
        # 填报申请headers
        re_headers = {
            'Host': 'stu.zstu.edu.cn',
            "sessionid": self.sessionID,
            "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
            "Cookie": "fine_auth_token=" + self.accessToken
        }

        # 填报post请求
        rep = requests.post(url=self.re_url, data=data, headers=re_headers)
        try:
            rep = json.loads(rep.text)
            print("打卡成功！返回信息：", rep[0]['fr_submitinfo'])
            logger.info("打卡成功！")
        except:
            # rep = rep.text
            print("打卡出错！返回信息：", rep)

    def read_by_json(self):
        """查看表单信息（这一步可以不进行，只是检查一下确定为健康申报表单）"""

        re_headers = {
            'Host': 'stu.zstu.edu.cn',
            "Authorization": "Bearer " + self.accessToken,
            "sessionid": self.sessionID,
            "Referer": self.re_url,
            "devicetype": "android",
            "Cookie": "fine_auth_token=" + self.accessToken
        }
        html = requests.get(
            url="http://stu.zstu.edu.cn/webroot/decision/view/report?op=fr_write&cmd=read_by_json&toVanCharts=true&dynamicHyperlink=true&sessionID=" + self.sessionID + "&reportIndex=0&pn=1&__cutpage__=",
            headers=re_headers)
        print(html.text)

    def run(self):
        self.login()
        self.report()


sp = reportE()


@app.route('/queryName', methods=['GET'])
def queryName():
    username = request.args.get("username")
    password = request.args.get("password")
    print(username, "  ", password)
    if sp.login(username, password) == 1:
        logger = E_log.logger_config(log_path='ELOG.txt', logging_name='E浙理打卡')
        logger.info('定时打卡开始运行，每天00：02准时打卡')
        logger.info('开始登陆：')
        sp.login()
        sp.report()

        schedule.every().day.at('00:02').do(sp.run)
        while True:
            schedule.run_pending()
    print(username)
    return username + password


@app.after_request
def af_request(resp):
    """
    #请求钩子，在所有的请求发生后执行，加入headers。
    :param resp:
    :return:
    """
    resp = make_response(resp)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'
    resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
    return resp


if __name__ == '__main__':
    server = make_server('0.0.0.0', 8585, app=app)
    server.serve_forever()
